<template>
  <div class="scheduli-list">
    <div class="toolbar">
      <el-date-picker v-model="current" type="month" value-format="YYYY-MM" format="YYYY-MM" @change="load" />
      <el-select v-model="defaultShiftName" placeholder="默认班次(用于空白工作日)" style="width:220px">
        <el-option v-for="s in allShiftNames" :key="s" :label="s" :value="s" />
      </el-select>
      <el-button type="primary" @click="goAdd">新增排班</el-button>
      <el-tag type="info" effect="light">班组: {{ teams.length }} 个</el-tag>
    </div>

    <div class="grid-wrapper">
      <table class="sched-table">
        <thead>
          <tr>
            <th class="col-name">班组</th>
            <th v-for="d in days" :key="d.key" class="col-day">
              <div class="day-top">{{ d.date }}</div>
              <div class="day-week">{{ d.weekLabel }}</div>
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="t in teams" :key="t.teamId">
            <td class="team-name">{{ t.teamName }}</td>
            <td v-for="d in days" :key="d.key" class="cell" :class="cellClass(t.teamId, d.key)" :style="{ backgroundColor: getShiftColor(t.teamId, d.key) }" @click="openEdit(t.teamId, d.key)">
              <span class="cell-text">{{ getShift(t.teamId, d.key) }}</span>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <el-dialog v-model="editVisible" title="编辑排班" width="420px" :close-on-click-modal="false">
      <div class="edit-form">
        <el-form :model="editForm" label-width="96px">
          <el-form-item label="日期">
            <el-input v-model="editForm.dateKey" disabled />
          </el-form-item>
          <el-form-item label="设为休息">
            <el-switch v-model="editForm.isRest" @change="onRestToggle" />
          </el-form-item>
          <el-form-item label="班次">
            <el-select v-model="editForm.shiftId" placeholder="选择班次" filterable style="width:100%">
              <el-option v-for="opt in shiftOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="紧急排班">
            <el-switch v-model="editForm.isUrgentSchedule" />
          </el-form-item>
          <el-form-item label="紧急订单">
            <el-switch v-model="editForm.isUrgentOrder" />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button @click="editVisible=false">取消</el-button>
        <el-button type="primary" :loading="savingEdit" @click="submitEdit">保存</el-button>
      </template>
    </el-dialog>
  </div>
  
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { getReadClient, getWriteClient } from '@/Urls/AxiosHelper'
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()
const read = getReadClient(1)
const write = getWriteClient(1)
const current = ref<string>(new Date().toISOString().slice(0,7))

// 初始化月份：优先使用路由 query，其次 localStorage
function initMonth(){
  const q = String(route.query.month || '').trim()
  const saved = localStorage.getItem('sched-current-month') || ''
  const val = q || saved
  if(/^\d{4}-\d{2}$/.test(val)) current.value = val
}

function goAdd(){
  router.push({ path: '/Main/ScheduleAdd', query: { month: current.value } })
}
// 接口数据
const rawSchedules = ref<any[]>([])
// 班组行
const teams = ref<any[]>([])
// 月份天
const days = computed(()=> buildDays(current.value))

// 默认班次名（用于工作日没有具体数据时填充）
const defaultShiftName = ref<string>('')
const allShiftNames = computed(()=>{
  const set = new Set<string>()
  rawSchedules.value.forEach(x=>{ if(x?.shiftName) set.add(String(x.shiftName)) })
  return Array.from(set)
})



function buildDays(ym: string){
  const [y,m] = ym.split('-').map(n=> Number(n))
  const last = new Date(y, m, 0)
  const arr:any[] = []
  for(let d=1; d<= last.getDate(); d++){
    const date = new Date(y, m-1, d)
    const key = formatDate(date)
    arr.push({ key, date: d, week: date.getDay(), weekLabel: weekMap[date.getDay()] })
  }
  return arr
}
const weekMap = ['日','一','二','三','四','五','六']
function formatDate(d: Date){
  const y = d.getFullYear(); const m = String(d.getMonth()+1).padStart(2,'0'); const day = String(d.getDate()).padStart(2,'0')
  return `${y}-${m}-${day}`
}

// teamId + dateKey → { shift, urgent, ids, color }
const schedMap = computed<Record<string,{
  shift: string,
  urgent: boolean,
  scheduleId?: number|string,
  calenDarId?: number|string,
  scheduleDate?: string,
  shiftId?: number|string,
  shiftColor?: string,
}>>(()=>{
  const map: Record<string,{shift:string, urgent:boolean, scheduleId?: number|string, calenDarId?: number|string, scheduleDate?: string, shiftId?: number|string, shiftColor?: string}> = {}
  for(const item of rawSchedules.value){
    const teamId = item?.teamId ?? item?.TeamId ?? item?.teamID ?? item?.TeamID
    // 优先使用 scheduleDate，其次 calendarDate
    const dateKey = normDate(item?.scheduleDate || item?.ScheduleDate || item?.calendarDate || item?.CalendarDate || item?.date)
    const shift = item?.shiftName ?? item?.ShiftName ?? item?.shift ?? item?.Shift ?? item?.shiftDisplayName ?? item?.ShiftDisplayName ?? ''
    const urgent = toBool(
      item?.isUrgentWorkday ?? item?.IsUrgentWorkday ??
      item?.isUrgentSchedule ?? item?.IsUrgentSchedule
    )
    const scheduleId = item?.scheduleId ?? item?.ScheduleId ?? item?.id ?? item?.Id
    const calenDarId = item?.calenDarId ?? item?.CalenDarId ?? item?.calendarId ?? item?.CalendarId
    const scheduleDate = normDate(item?.scheduleDate || item?.ScheduleDate || item?.calendarDate || item?.CalendarDate)
    const shiftId = item?.shiftId ?? item?.ShiftId ?? item?.shiftID ?? item?.ShiftID
    const shiftColor = item?.displayColor ?? item?.DisplayColor ?? item?.shiftColor ?? item?.ShiftColor
    
    if(teamId!=null && dateKey){
      map[`${teamId}_${dateKey}`] = {
        shift:String(shift||''),
        urgent,
        scheduleId,
        calenDarId,
        scheduleDate: scheduleDate ? `${scheduleDate}T00:00:00.000Z` : undefined,
        shiftId,
        shiftColor: shiftColor ? String(shiftColor).trim() : undefined,
      }
      // 调试输出：确认真实数据已覆盖
      console.log('[排班映射]', teamId, dateKey, '=>', map[`${teamId}_${dateKey}`])
    }
  }
  return map
})
function normDate(v:any){
  if(!v) return ''
  const s = String(v)
  if(/^\d{4}-\d{2}-\d{2}$/.test(s)) return s
  if(/^\d{4}-\d{2}-\d{2}[ T]/.test(s)) return s.slice(0,10)
  const d = new Date(s); if(!isNaN(d.getTime())) return formatDate(d)
  return ''
}
function toBool(v:any){
  if(typeof v==='boolean') return v
  if(typeof v==='number') return v===1
  if(typeof v==='string') return ['true','1','y','是'].includes(v.trim().toLowerCase())
  return false
}

function getShift(teamId:number|string, dateKey:string){
  const key = `${teamId}_${dateKey}`
  const data = schedMap.value[key]
  if(data){
    // 优先显示实际的班次名称，不管是否为紧急排班
    if(data.shift && data.shift.trim()){
      const val = data.shift.trim()
      const urgentText = data.urgent ? ' (紧急)' : ''
      console.log('[排班显示]', getTeamNameById(teamId), dateKey, '=>', val, `(实际排班${urgentText})`)
      return val
    }
    // 如果没有班次名称但有排班记录，显示为"待安排"
    const val = '待安排'
    console.log('[排班显示]', getTeamNameById(teamId), dateKey, '=>', val, '(排班记录无班次)')
    return val
  }
  // 没有排班数据时的处理
  const w = new Date(dateKey).getDay()
  if(w===0 || w===6){
    const val = '休'
    console.log('[排班显示]', getTeamNameById(teamId), dateKey, '=>', val, '(周末)')
    return val
  }
  // 工作日没有排班数据时，显示为空或默认班次
  const val = defaultShiftName.value || ''
  console.log('[排班显示]', getTeamNameById(teamId), dateKey, '=>', val || '(无排班)', '(默认)')
  return val
}
function firstShiftFallback(){
  return allShiftNames.value[0] || '班'
}

function getTeamNameById(id:any){
  const t = teams.value.find(x=> x?.teamId === id)
  return t?.teamName || `班组-${id}`
}

function isRest(teamId:number|string, dateKey:string){
  const text = getShift(teamId, dateKey)
  return text === '休' || text === '休息'
}

function getShiftColor(teamId:number|string, dateKey:string){
  const key = `${teamId}_${dateKey}`
  const data = schedMap.value[key]
  
  // 如果有排班记录且有颜色信息，直接返回
  if(data && data.shiftColor) {
    return data.shiftColor
  }
  
  // 如果有排班记录但没有颜色信息，尝试从班次选项中获取颜色
  if(data && data.shift && data.shift.trim() && !isRest(teamId, dateKey)) {
    const shiftOption = shiftOptions.value.find(opt => opt.label === data.shift)
    if(shiftOption && shiftOption.color) {
      return shiftOption.color
    }
  }
  
  // 如果是休息日
  if(isRest(teamId, dateKey)) {
    return '#e8f5e9' // 休息日的默认绿色
  }
  
  // 如果是周末，显示休息颜色
  const w = new Date(dateKey).getDay()
  if(w === 0 || w === 6) {
    return '#e8f5e9' // 周末的绿色
  }
  
  // 工作日没有排班数据时，使用默认班次的颜色
  if(defaultShiftName.value) {
    const defaultShiftOption = shiftOptions.value.find(opt => opt.label === defaultShiftName.value)
    if(defaultShiftOption && defaultShiftOption.color) {
      return defaultShiftOption.color
    }
  }
  
  // 最后的默认颜色
  return '#ffd6d6' // 工作日的默认红色
}

function cellClass(teamId:number|string, dateKey:string){
  const key = `${teamId}_${dateKey}`
  const data = schedMap.value[key]
  const hasCustomColor = !!(data?.shiftColor || (data?.shift && shiftOptions.value.find(opt => opt.label === data.shift)?.color))
  
  return {
    rest: isRest(teamId, dateKey),
    busy: !isRest(teamId, dateKey),
    'has-color': hasCustomColor,
  }
}

async function load(){
  try{
    const [schedRes, teamRes, shiftRes] = await Promise.all([
      read.get('schedread/api/Team/GetSchedules', { params: { month: current.value } }),
      read.get('schedread/api/Team/GetTeam', { params: { pageindex:1, pagesize:1000 } }),
      read.get('schedread/api/Team/GetShift') // 同时加载班次信息
    ])

    const sdata = Array.isArray(schedRes?.data) ? schedRes.data : (schedRes?.data?.data ?? [])
    rawSchedules.value = Array.isArray(sdata) ? sdata : []

    // 班组列表从 GetTeam 获取，按接口字段映射
    const tdata = teamRes?.data?.data
    const tlist = tdata?.data || tdata || teamRes?.data || []
    teams.value = (Array.isArray(tlist) ? tlist : []).map((x:any)=> ({
      teamId: x?.teamId ?? x?.TeamId ?? x?.id ?? x?.Id,
      teamName: x?.teamName ?? x?.TeamName ?? `班组-${x?.teamId ?? x?.id}`
    })).filter((x:any)=> x.teamId!=null)

    // 初始化班次选项（包含颜色信息）
    const shifts = Array.isArray(shiftRes?.data) ? shiftRes.data : (shiftRes?.data?.data ?? [])
    shiftOptions.value = shifts.map((s:any)=>({
      label: s.shiftName || s.ShiftName || `班次${s.shiftId || s.id}`,
      value: s.shiftId || s.id,
      color: s.displayColor || s.DisplayColor || s.shiftColor || s.ShiftColor || '#4CAF50' // 默认绿色
    }))

    // 默认班次名称：优先使用新增页记录
    const saved = localStorage.getItem(`sched-default-${current.value}`)
    if(saved){
      defaultShiftName.value = saved
    }else if(!defaultShiftName.value){
      defaultShiftName.value = firstShiftFallback()
    }
  }catch(e:any){
    ElMessage.error(e?.message || '获取排班失败')
  }
}

// 编辑逻辑
const editVisible = ref(false)
const editForm = ref<any>({
  teamId: undefined,
  dateKey: '',
  scheduleId: undefined,
  shiftId: undefined,
  shiftName: '',
  isRest: false,
  isUrgentSchedule: false,
  isUrgentOrder: false,
  calenDarId: undefined,
})
const shiftOptions = ref<Array<{label:string,value:number|string,color?:string}>>([])
const savingEdit = ref(false)

async function openEdit(teamId:number|string, dateKey:string){
  const key = `${teamId}_${dateKey}`
  const existing = schedMap.value[key]
  try {
    const shiftRes = await read.get('schedread/api/Team/GetShift')
    const shifts = Array.isArray(shiftRes?.data) ? shiftRes.data : (shiftRes?.data?.data ?? [])
    shiftOptions.value = shifts.map((s:any)=>({
      label: s.shiftName || s.ShiftName || `班次${s.shiftId || s.id}`,
      value: s.shiftId || s.id,
      color: s.displayColor || s.DisplayColor || s.shiftColor || s.ShiftColor || '#4CAF50' // 默认绿色
    }))
  } catch {}
  
  // 初始化编辑表单
  editForm.value = {
    teamId: Number(teamId),
    dateKey,
    scheduleId: existing?.scheduleId,
    shiftId: undefined,
    shiftName: existing?.shift || '',
    isRest: (existing?.shift === '休' || existing?.shift === '休息'),
    // 只有在确实存在紧急排班标记且不是休息时才勾选紧急排班
    isUrgentSchedule: !!existing?.urgent && existing?.shift !== '休' && existing?.shift !== '休息',
    isUrgentOrder: false,
    calenDarId: existing?.calenDarId ?? 1,
  }
  
  // 更准确地匹配现有班次
  if(existing?.shift && existing.shift.trim() && !editForm.value.isRest) {
    // 先尝试精确匹配班次名称
    const exactMatch = shiftOptions.value.find(o => o.label.trim() === existing.shift.trim())
    if(exactMatch) {
      editForm.value.shiftId = exactMatch.value
      console.log('[班次匹配] 精确匹配:', existing.shift, '=>', exactMatch.value)
    } else {
      // 如果没有精确匹配，尝试包含匹配
      const partialMatch = shiftOptions.value.find(o => o.label.includes(existing.shift) || existing.shift.includes(o.label))
      if(partialMatch) {
        editForm.value.shiftId = partialMatch.value
        console.log('[班次匹配] 包含匹配:', existing.shift, '=>', partialMatch.value)
      } else {
        console.log('[班次匹配] 未找到匹配的班次:', existing.shift, '可用选项:', shiftOptions.value.map(o => o.label))
      }
    }
  } else if(editForm.value.isRest) {
    // 如果是休息日，查找休息班次
    const restOpt = shiftOptions.value.find(o => o.label === '休' || o.label === '休息')
    if(restOpt) {
      editForm.value.shiftId = restOpt.value
    }
  }
  
  editVisible.value = true
}

function onRestToggle(){
  if(editForm.value.isRest){
    // 切换到休息时，清除紧急排班选项
    editForm.value.isUrgentSchedule = false
    editForm.value.isUrgentOrder = false
    
    // 查找休息班次选项
    const restOpt = shiftOptions.value.find(o=> o.label==='休' || o.label==='休息')
    if(restOpt){ 
      editForm.value.shiftId = restOpt.value
      editForm.value.shiftName = restOpt.label
      console.log('[切换休息] 设置为:', restOpt.label, restOpt.value)
    } else {
      // 如果没有找到休息选项，清空班次选择
      editForm.value.shiftId = undefined
      editForm.value.shiftName = ''
      console.log('[切换休息] 未找到休息班次选项')
    }
  } else {
    // 切换到正常班次时，恢复之前的班次选择（如果有的话）
    if(!editForm.value.shiftId && editForm.value.shiftName) {
      const match = shiftOptions.value.find(o => o.label === editForm.value.shiftName)
      if(match) {
        editForm.value.shiftId = match.value
        console.log('[切换正常班次] 恢复:', match.label, match.value)
      }
    }
  }
}

async function submitEdit(){
  try{
    if(!editForm.value.shiftId){
      ElMessage.warning('请选择班次')
      return
    }
    savingEdit.value = true
    
    // 获取选中的班次信息
    const selectedShift = shiftOptions.value.find(o => o.value === editForm.value.shiftId)
    const shiftName = selectedShift?.label || editForm.value.shiftName || ''
    const shiftColor = selectedShift?.color || '#4CAF50' // 默认绿色
    
    // 构建提交数据
    const payload:any = {
      teamId: Number(editForm.value.teamId),
      shiftId: Number(editForm.value.shiftId),
      scheduleDate: `${editForm.value.dateKey}T00:00:00.000Z`,
      calenDarId: editForm.value.calenDarId ?? 1,
      shiftName: shiftName,
      displayColor: shiftColor, // 添加颜色信息
    }
    
    // 处理休息和紧急排班逻辑
    if(editForm.value.isRest) {
      // 休息日：不设置紧急排班相关字段
      payload.shiftName = '休'
      payload.isUrgentSchedule = false
      payload.isUrgentWorkday = false
      payload.isUrgentOrder = false
    } else {
      // 正常班次：默认不设置紧急排班，只有用户明确勾选时才设置
      payload.isUrgentSchedule = false  // 默认不紧急
      payload.isUrgentWorkday = false   // 默认不紧急
      payload.isUrgentOrder = false     // 默认不紧急
      
      // 只有在用户明确勾选时才设置为紧急
      if(editForm.value.isUrgentSchedule) {
        payload.isUrgentSchedule = true
        payload.isUrgentWorkday = true
      }
      if(editForm.value.isUrgentOrder) {
        payload.isUrgentOrder = true
      }
    }
    
    console.log('[提交排班]', payload)
    
    if(editForm.value.scheduleId != null){
      payload.scheduleId = editForm.value.scheduleId
      await write.post('schedwrite/api/Team/UpdSchedule', payload)
      console.log('[更新排班] 成功')
    }else{
      // 虚拟单元格 → 新增为真实记录
      await write.post('schedwrite/api/Team/AddSchedule', payload)
      console.log('[新增排班] 成功')
    }
    
    ElMessage.success('保存成功')
    editVisible.value = false
    await load()
  }catch(e:any){
    console.error('[提交排班] 失败:', e)
    ElMessage.error(e?.message || '保存失败')
  }finally{
    savingEdit.value = false
  }
}

// 同步月份的持久化与路由
watch(current, (ym)=>{
  if(/^\d{4}-\d{2}$/.test(ym)){
    localStorage.setItem('sched-current-month', ym)
    const cur = String(route.query.month || '')
    if(cur !== ym){ router.replace({ query: { ...route.query, month: ym } }) }
    load()
  }
})

onMounted(()=>{
  initMonth()
  load()
})
</script>

<style scoped>
.scheduli-list{ padding: 12px; }
.toolbar{ display:flex; align-items:center; gap:8px; margin-bottom:8px; }
.grid-wrapper{ overflow:auto; border:1px solid #e5e7eb; border-radius:6px; }
.sched-table{ border-collapse:collapse; width: max-content; min-width:100%; table-layout: fixed; }
.sched-table th, .sched-table td{ border:1px solid #e5e7eb; padding:6px; text-align:center; }
.col-name{ position:sticky; left:0; background:#fff; z-index:2; width:120px; min-width:120px; }
.team-name{ position:sticky; left:0; background:#fff; z-index:1; width:120px; min-width:120px; font-weight:600; }
.col-day{ min-width:36px; width:36px; }
.day-top{ font-weight:600; }
.day-week{ color:#999; font-size:12px; }
.cell{ 
  min-width:36px; 
  height:28px; 
  cursor: pointer;
  transition: all 0.2s ease;
}
.cell:hover {
  opacity: 0.8;
  transform: scale(1.02);
}
.cell.rest{ background:#e8f5e9; }
.cell.busy{ background:#ffd6d6; }
.cell.has-color {
  /* 当有自定义颜色时，覆盖默认的rest/busy样式 */
  border: 1px solid rgba(0,0,0,0.1);
}
.cell-text{ 
  font-size:12px; 
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
</style>


